# ========================================
# RISC-V 最小操作系统启动入口点
# ========================================
# 
# 这个文件是整个操作系统的入口点，当CPU上电后，QEMU会将内核加载到
# 内存地址0x80000000，然后跳转到这里开始执行。
#
# 启动流程：
# 1. CPU上电 → 2. QEMU加载内核 → 3. 跳转到_entry → 4. 设置栈 → 5. 清零BSS → 6. 调用main
#

# 定义代码段，所有可执行代码都放在这里
.section .text
# 声明_entry为全局符号，这样链接器就知道这是程序的入口点
.global _entry

# 程序入口点：_entry
# 这是CPU上电后第一个执行的代码
_entry:
    # ========================================
    # 第一步：设置栈指针 (Stack Pointer)
    # ========================================
    # 
    # 为什么需要设置栈？
    # - C语言函数调用需要栈来保存局部变量、函数参数和返回地址
    # - 没有栈，C函数就无法正常工作
    # - 栈是函数调用约定的基础
    #
    # la指令：Load Address，将地址加载到寄存器
    # sp：Stack Pointer，栈指针寄存器
    # stack_top：我们定义的栈顶地址（在文件末尾定义）
    la sp, stack_top
    
    # ========================================
    # 第二步：清零BSS段 (Block Started by Symbol)
    # ========================================
    #
    # 什么是BSS段？
    # - BSS段存放所有未初始化的全局变量和静态变量
    # - 例如：int global_var; 这样的变量就放在BSS段
    # - C标准规定这些变量在程序启动时应该为0
    #
    # 为什么要手动清零？
    # - BSS段在可执行文件中不占空间，只记录大小
    # - 程序启动时，BSS段的内容是随机的垃圾数据
    # - 我们必须手动清零，确保变量初始值为0
    #
    
    # 加载BSS段的起始地址到t0寄存器
    la t0, bss_start
    # 加载BSS段的结束地址到t1寄存器  
    la t1, bss_end

# BSS清零循环
clear_bss:
    # 比较t0和t1，如果相等说明已经清零完毕
    beq t0, t1, bss_cleared
    
    # 将0写入t0指向的内存地址（清零4字节）
    sw zero, 0(t0)
    
    # t0指针向前移动4字节（RISC-V是32位架构，一次清零4字节）
    addi t0, t0, 4
    
    # 跳回循环开始，继续清零下一块内存
    j clear_bss

# BSS清零完成标签
bss_cleared:
    
    # ========================================
    # 第三步：跳转到C语言主函数
    # ========================================
    #
    # call指令：调用函数
    # main：C语言的主函数
    # 此时栈已设置，BSS已清零，可以安全调用C函数
    call main
    
    # ========================================
    # 第四步：防止程序意外退出
    # ========================================
    #
    # 如果main函数返回（虽然我们的main是无限循环），
    # 程序会继续执行到这里。为了避免系统重启，
    # 我们进入一个无限循环。
    #
spin:
    # 无条件跳转到自己，形成无限循环
    j spin

# ========================================
# 栈空间定义
# ========================================
#
# 定义BSS段，用于存放未初始化的全局变量和栈空间
.section .bss
# 16字节对齐，提高内存访问效率
.align 16

# 栈底地址（栈从高地址向低地址增长）
stack_bottom:
    # 分配4KB的栈空间（4096字节）
    # 对于最小操作系统来说，4KB足够使用
    .space 4096

# 栈顶地址（栈指针sp指向这里）
stack_top:
